package com.tsp_tux.demo.Util;

import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class F302 {
    private final HashMap<String, String> cookies = new HashMap<>();

    public String request(String url) throws IOException {
        do {
            log.info("request url: {}", url);
            HttpURLConnection httpURLConnection = (HttpURLConnection) new URL(url).openConnection();
            httpURLConnection.setInstanceFollowRedirects(false);
            httpURLConnection.setRequestProperty("Cookie", getCookieString());
            httpURLConnection.connect();
            parseCookie(httpURLConnection.getHeaderFields().get("Set-Cookie"));
            int code = httpURLConnection.getResponseCode();
            if (code == 302) {
                url = httpURLConnection.getHeaderField("Location");
                continue;
            }
            if (code == 200) {
                return readFully(httpURLConnection.getInputStream());
            }
            throw new IOException("http code = " + code);
        } while (true);
    }

    private String getCookieString() {
        StringBuilder builder = new StringBuilder();
        cookies.forEach((k, v) -> builder.append(k).append("=").append(v).append("; "));
        if (builder.length() != 0) {
            builder.deleteCharAt(builder.length() - 1);
            builder.deleteCharAt(builder.length() - 1);
        }
        return builder.toString();
    }

    private void parseCookie(List<String> cookies) {
        Pattern pattern = Pattern.compile("([^=]+)=([^;]+);");
        Optional.ofNullable(cookies).orElseGet(Collections::emptyList).forEach(item -> {
            Matcher matcher = pattern.matcher(item);
            if (matcher.find()) {
                this.cookies.put(matcher.group(1), matcher.group(2));
            }
        });
    }

    private String readFully(InputStream inputStream) throws IOException {
        StringBuilder builder = new StringBuilder();
        try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader((inputStream)))) {
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                builder.append(line).append("\n");
            }
        }
        return builder.toString();
    }
}
